


#include "udp_socket.h"



#define UDP_LOG_DOMAN       "udp-socket"
#define udp_debug(...)  	qelog_debug(UDP_LOG_DOMAN, __VA_ARGS__)
#define udp_info(...)   	qelog_info(UDP_LOG_DOMAN, __VA_ARGS__)
#define udp_notice(...) 	qelog_notice(UDP_LOG_DOMAN, __VA_ARGS__)
#define udp_warning(...)    qelog_warning(UDP_LOG_DOMAN, __VA_ARGS__)
#define udp_critical(...)   qelog_critical(UDP_LOG_DOMAN, __VA_ARGS__)
#define udp_error(...)  	qelog_error(UDP_LOG_DOMAN, __VA_ARGS__)
#define udp_fatal(...)		qelog_fatal(UDP_LOG_DOMAN, __VA_ARGS__)
#define udp_hexdump(...)    qehex_debug(UDP_LOG_DOMAN, __VA_ARGS__)



qe_ret udp_socket_init(udp_socket *sock, 
    const char *address, qe_u16 port)
{
    WSAStartup(MAKEWORD(2, 2), &sock->ws);

    sock->s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (!sock->s) {
        udp_error("socket create error");
        return qe_err_common;
    }

    sock->server_addr.sin_family = AF_INET;
    if (address) {
        sock->server_addr.sin_addr.s_addr = inet_addr(address);
    } else {
        sock->server_addr.sin_addr.s_addr = inet_addr(INADDR_ANY);
    }
    
    sock->server_addr.sin_port = htons(port);

    sock->client_addr_len = sizeof(sock->client_addr);
    
    udp_debug("udp socket init with %s:%d", address, port);
    
    return qe_ok;
}

qe_ret udp_socket_bind(udp_socket *sock)
{
    int r;

    r = bind(sock->s, (struct sockaddr *)&sock->server_addr, 
        sizeof(sock->server_addr));
    if (r < 0) {
        udp_error("socket bind error");
        return qe_err_common;
    }

    return qe_ok;
}

qe_ret udp_socket_send(udp_socket *sock, char *buf, int size)
{
    int n;

    n = sendto(sock->s, buf, size, 0, 
            (struct sockaddr *)&sock->client_addr, 
            sizeof(sock->client_addr));
    if (n < 0) {
        udp_error("send error");
        return qe_err_send;
    }

    if (n != size) {
        udp_warning("send size error, %d %d", n, size);
    }

    return qe_ok;
}

qe_ret udp_socket_recv(udp_socket *sock, char *buf, int size, int *rxsize)
{
    int n;

    n = recvfrom(sock->s, buf, size, 0, 
            (struct sockaddr *)&sock->client_addr,
            &sock->client_addr_len);
    if (n < 0) {
        udp_error("recv error");
        return qe_err_common;
    }

    *rxsize = n;

    return qe_ok;
}

void udp_socket_exit(udp_socket *sock)
{
    if (sock->s) {
        closesocket(sock->s);
        WSACleanup();
        udp_debug("udp socket exit");
    }
}